using System;
namespace Lizk.SimpleHUD
{
    [Serializable]
    public class HUDMoveList : HUDContainerSimple
    {
        protected int startIndex = 0;
        protected int selectedIndex = 0;
        [NonSerialized]
        protected int itemsShown = 0;
        protected SizeS itemSize;
        protected RectangleS selection;
        protected bool horizontal, moving;
        private PointS listOffset = new PointS();

        public event EventHandler<SelectionEventArgs> SelectedIndexChanged;

        public event EventHandler SelectedStoppedMoving;

        public PointS Offset
        {
            get { return listOffset; }
            set { listOffset = value; }
        }

        public RectangleS Selection
        {
            get { return selection; }
        }

        public SizeS ItemSize
        {
            get { return itemSize; }
            set { itemSize = value; }
        }

        public bool IsHorizontal { get { return horizontal; } }


        public HUDMoveList(SizeS itemSize, bool horizontal)
        {
            this.itemSize = itemSize;
            this.horizontal = horizontal;
        }

        public void Add(HUDControl item, bool animate)
        {
            base.Add(item);
            MoveItems(animate);
        }

        public int VisibleItems
        {
            get { return itemsShown; }
        }


        public override void ResizeMove(RectangleS oldRect, RectangleS newRect)
        {
            itemsShown = horizontal ? (int)(newRect.Width / itemSize.Width) -1 : (int)(newRect.Height / itemSize.Height) -1;
            base.ResizeMove(oldRect, newRect);
        }
        public virtual int StartIndex
        {
            get
            {
                return startIndex;
            }
            set
            {
                if (startIndex != value)
                {
                    startIndex = value;
                    MoveItems(true);
                }
            }
        }

        public virtual void SetStartIndex(int value, bool animate)
        {
            startIndex = value;
            MoveItems(animate);
        }

        public virtual int SelectedIndex
        {
            get
            {
                return selectedIndex;
            }
            set 
            {
                if (selectedIndex != value)
                {
                    int old = selectedIndex;
                    selectedIndex = value;
                    MoveItems(true);

                    if (old != selectedIndex && SelectedIndexChanged != null)
                        SelectedIndexChanged(this, new SelectionEventArgs(old, true));

                }
            }
        }

        public virtual void SetSelectedIndex(int value, bool animate)
        {
            int old = selectedIndex;
            selectedIndex = value;
            MoveItems(animate);

            if (old != selectedIndex && SelectedIndexChanged != null)
                SelectedIndexChanged(this, new SelectionEventArgs(old, animate));

        }

        public virtual void SetIndices(int start, int selected, bool animate)
        {
            startIndex = start;
            selectedIndex = selected;
            MoveItems(animate);
        }

        public T GetSelectedControl<T>() where T : HUDControl
        {
            return (T)controls[selectedIndex];
        }

        public HUDControl SelectedControl
        {
            get { if (selectedIndex >= 0 && selectedIndex < Count) return controls[selectedIndex]; else return null;  }
        }

        public override void Update(TimeSpan ts)
        {
            base.Update(ts);

            if (moving)
            {



                if (SelectedControl == null)
                    moving = false;
                else
                {
                    if (!SelectedControl.IsMoving)
                    {
                        moving = false;
                        if (SelectedStoppedMoving != null)
                             SelectedStoppedMoving(this, null);
                    }
                }
            }

        }

        public virtual void MoveItems(bool animate)
        {
            if (selectedIndex < 0)
                selectedIndex = 0;
            if (selectedIndex >= controls.Count)
                selectedIndex = controls.Count - 1;
            
            if (selectedIndex < startIndex)
                startIndex = selectedIndex;

            if (selectedIndex >= startIndex + itemsShown)
                startIndex = selectedIndex - itemsShown;

            selection = new RectangleS(!horizontal ? new PointS(listOffset.X, listOffset.Y + (selectedIndex - startIndex) * itemSize.Height) : new PointS((selectedIndex - startIndex) * itemSize.Width + listOffset.X, listOffset.Y), itemSize);

            for (int i = 0; i < controls.Count; i++)
            {
                PointS newPoint = horizontal ? new PointS(itemSize.Width * (i - startIndex) + listOffset.X, listOffset.Y) : new PointS(listOffset.X, listOffset.Y + itemSize.Height * (i - startIndex));
                
                if (animate)
                {
                    controls[i].Destination = newPoint;
                }
                else
                {
                    controls[i].Location = newPoint;
                }
            }
            if (SelectedControl != null)
            {
                if (!animate && SelectedStoppedMoving != null)
                    SelectedStoppedMoving(this, null);
                else
                    moving = true;
            }



        }
        
    }

    public class SelectionEventArgs : EventArgs
    {
        public int OldIndex { get; set; }
        public bool Animate { get; set; }
        public SelectionEventArgs(int oldIndex, bool animate)
        {
            OldIndex = oldIndex;
            this.Animate = animate;
        }
    }

}
